在開放原始碼的世界,有非常多厲害開發者願意無私的貢獻程式碼,而這些程式碼大多會打包成好用的套件,在 Ruby 的世界,我們稱它為 Gem。-- 為你自己學 Ruby on Rails
俗話說:「總有一顆寶石能幫到你。」採礦區:RubyGems
當我們 new 一個 Rails 專案時,根目錄下會有個名稱為 Gemfile
的檔案,就是專門放置套件的地方,搭配幫手 Bundler
, Bundler 是管理 Gem 相依性的工具,執行 bundle install 時,會根據 Gemfile 檢查指定的 Gem 與相依套件是否已安裝,如果已安裝就會顯示 Using,如果是新下載安裝的 Gem,就會顯示 Installing 。
當我們用終端機產生專案時,一般狀況下,產生完預設的檔案後,會自動 run bundle install 直到完成。
完成後打開專案進入 Gemfile
檔案會看到如下一大串程式碼,後面的數字就是版號:
gem 'sqlite3' # 未註明版號,安裝最新的穩定版本
ruby '2.6.3' # 安裝註明的版本
gem 'sass-rails', '~> 5.0' # 安裝 5.0 以上,5.1 以下(不含5.1)的版本
例如版本號 2.6.3,三個數字分別代表:主要版號(Major)、次要版號(Minor)以及修訂版號(Patch)
~>
可以比較確保在進行 bundle install 指令的時候,只會更新到次要或修訂版號的套件。為什麼會需要版號的規範呢?當專案加入的套件越來越多,新版的定義大家各說各話,可以想像相容性及支援度必會產生極大混亂,因此 Gravatars 創辦者兼 GitHub 共同創辦者 Tom Preston-Werner 建立了一個語意化版本控制規範(SemVer)。這不是強制的,但幾乎大部份的 Gem 作者都有這樣的共識。
舉個簡單的例子就可以展示語意化的版本控制如何讓相依性地獄成為過去。假設有個名為「救火車」的函式庫,它需要另一個名為「梯子」並已經有使用語意化版本控制的套件。當救火車創建時,梯子的版號為 3.1.0。因為救火車使用了一些版本 3.1.0 所新增的功能,你可以放心地指定相依於梯子的版號大等於 3.1.0 但小於4.0.0。這樣,當梯子版本 3.1.1和 3.2.0 發佈時,你可以將直接它們納入你的套件管理系統,因為它們能與原有相依的軟體相容。 -- 語意化版本 2.0.0
在 gemfile 檔案裡可以設定 group 將套件用 block 包起來,依據載入環境來分類,以下的程式碼是指 開發
以及 測試
用,你也可以將之分開:
group :development, :test do
gem 'hirb-unicode', '~> 0.0.5'
gem 'faker', '~> 2.1', '>= 2.1.2'
gem 'factory_bot_rails', '~> 5.0', '>= 5.0.2' #安裝5.0以上
end
也就是說,放在這個群組內的套件就只會在開發或測試的環境下有用,這樣在正式上線版本時這些用不到的套件就不需載入了。
當進行第一次 bundle install 時,會隨之產生一個 Gemfile.lock 的檔案,不同於 gmefile 裡的套件版本可能是一個範圍,它會記載已安裝的套件詳細名稱及確切的版本,相當於記載了一個相依藍圖,通常我們將專案抓回來後會先做兩件事:bundle
及 db:migrate
,如果 bundle 時 Gemfile.lock 已經存在,它會考慮已經存在於該檔的版來安装,而不是僅依靠 gemfile 來安裝最新版本,這樣除了確保你自己也確保協作者或 server 都能使用相同版本。請記得新增或是刪除 gem 都要 bundle install,而 gemfile.lock 會隨之更新!